﻿using AudioStudio;
using AudioStudio.Tools;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
using Yoozoo.Core.Extensions.CSharp;
using Yoozoo.Gameplay.Managers.ResourceManagerV2.Editor;
using Yoozoo.Managers.ResourceManagerV2.Framework;
using Yoozoo.Managers.ResourceManagerV2.Framework.Resource;
using Yoozoo.Managers.ResourceManagerV2.Runtime;
using Yoozoo.Modules.Download;

namespace Yoozoo.Managers.ResourceManagement
{
    public class DownloadPriorityDataCreator
    {
        public static bool ReadWriteVersionListTryGetHeaderCallback(Stream stream, out LocalVersionList localVersionList)
        {
            localVersionList = default(LocalVersionList);
            return true;
        }

        [MenuItem("GTATools/打包/导出下载列表到优先级列表")]
        public static void AddFromVersionList()
        {
            try
            {
                string file = EditorUtility.OpenFilePanel("选择下载列表", Application.dataPath, "dat");

                var serializer = new ReadWriteVersionListSerializer();
                serializer.RegisterTryGetHeaderCallback(0, ReadWriteVersionListTryGetHeaderCallback);
                serializer.RegisterTryGetHeaderCallback(1, ReadWriteVersionListTryGetHeaderCallback);
                serializer.RegisterTryGetHeaderCallback(2, ReadWriteVersionListTryGetHeaderCallback);
                serializer.RegisterTryGetHeaderCallback(3, ReadWriteVersionListTryGetHeaderCallback);

                serializer.RegisterSerializeCallback(0, BuiltinVersionListSerializer.LocalVersionListSerializeCallback_V0);
                serializer.RegisterSerializeCallback(1, BuiltinVersionListSerializer.LocalVersionListSerializeCallback_V1);
                serializer.RegisterSerializeCallback(2, BuiltinVersionListSerializer.LocalVersionListSerializeCallback_V2);
                serializer.RegisterSerializeCallback(3, BuiltinVersionListSerializer.LocalVersionListSerializeCallback_V3);

                serializer.RegisterDeserializeCallback(0, BuiltinVersionListSerializer.LocalVersionListDeserializeCallback_V0);
                serializer.RegisterDeserializeCallback(1, BuiltinVersionListSerializer.LocalVersionListDeserializeCallback_V1);
                serializer.RegisterDeserializeCallback(2, BuiltinVersionListSerializer.LocalVersionListDeserializeCallback_V2);
                serializer.RegisterDeserializeCallback(3, BuiltinVersionListSerializer.LocalVersionListDeserializeCallback_V3);

                var bytes = File.ReadAllBytes(file);
                try
                {
                    var unzip = Utility.ZipUtil.Decompress(bytes);
                    if (unzip != null)
                        bytes = unzip;
                }
                catch (Exception)
                {
                    // not zip file
                }

                using (var inStream = new MemoryStream(bytes))
                {
                    var versionList = serializer.Deserialize(inStream);
                    if (!versionList.IsValid)
                    {
                        Console.WriteLine("文件解析失败. {0}", versionList);
                        return;
                    }

                    var resourceNames = versionList.GetResources().Select(x => x.RawName).OrderBy(x => x).ToArray();

                    var data = ScriptableObject.CreateInstance<DownloadPriorityData>();
                    data.ResourceNames = resourceNames;

                    if (File.Exists(DownloadPriorityData.AssetPath))
                        AssetDatabase.DeleteAsset(DownloadPriorityData.AssetPath);
                    AssetDatabase.CreateAsset(data, DownloadPriorityData.AssetPath);
                }
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogException(e);
                return;
            }
            
            //CollectAudioAssets();
        }

        [MenuItem("GTATools/打包/音频文件加入到优先级列表")]
        public static void CollectAudioAssets()
        {
            var soundBankList = GtaVersionProcess.SoundBankList;

            var hashSet = new HashSet<string>();
            var xBanks = SoundBanksInfoReader.SoundBanksNode;

            var data = ScriptableObject.CreateInstance<DownloadPriorityData>();
            var resourceNames = new List<string>();

            string bankLoadPath = WwisePathSettings.GetBankLoadPath();

            foreach (var xBank in xBanks.Elements())
            {
                var shortName = AsScriptingHelper.GetXmlElement(xBank, "ShortName");
                var path = AsScriptingHelper.GetXmlElement(xBank, "Path");
                var language = AsScriptingHelper.GetXmlAttribute(xBank, "Language");

                var bankPath = Path.Combine(bankLoadPath, path);
                bankPath = Path.GetFullPath(bankPath).Replace("\\", "/");
                if (!File.Exists(bankPath))
                    continue;

                bool isIncludeFile = soundBankList.Contains(shortName);
                if (isIncludeFile)
                {
                    hashSet.Add(bankPath);
                }

                var xStreams = xBank.Element("ReferencedStreamedFiles");
                if (xStreams == null)
                {
                    if (!isIncludeFile)
                    {
                        string bankResourcePath = $"Audio/{WwisePathSettings.GetPlatformName()}/{path.Replace("\\", "/")}";
                        resourceNames.Add(bankResourcePath);
                    }
                    continue;
                }

                foreach (var xFile in xStreams.Elements())
                {
                    var id = AsScriptingHelper.GetXmlAttribute(xFile, "Id");
                    string fileName;
                    if (language == "SFX")
                        fileName = id + ".wem";
                    else
                        fileName = language + "/" + id + ".wem";

                    string filePath = Path.Combine(bankLoadPath, fileName);
                    string fullPath = Path.GetFullPath(filePath).Replace("\\", "/");
                    if (!File.Exists(fullPath))
                        continue;

                    if (isIncludeFile)
                    {
                        hashSet.Add(fullPath);
                    }
                    else
                    {
                        string resourcePath = $"Audio/{WwisePathSettings.GetPlatformName()}/{fileName}";
                        resourceNames.Add(resourcePath);
                    }
                }

                if (!isIncludeFile)
                {
                    string bankResourcePath = $"Audio/{WwisePathSettings.GetPlatformName()}/{path.Replace("\\", "/")}";
                    resourceNames.Add(bankResourcePath);
                }
            }

            if (File.Exists(DownloadPriorityData.AssetPath))
            {
                var oldData = AssetDatabase.LoadAssetAtPath<DownloadPriorityData>(DownloadPriorityData.AssetPath);
                if (oldData.ResourceNames.IsNotEmpty())
                {
                    foreach (var resourceName in oldData.ResourceNames)
                    {
                        if (!resourceName.StartsWith("Audio/"))
                        {
                            resourceNames.Add(resourceName);
                        }
                    }
                }
                AssetDatabase.DeleteAsset(DownloadPriorityData.AssetPath);
            }

            data.ResourceNames = resourceNames.ToArray();
            AssetDatabase.CreateAsset(data, DownloadPriorityData.AssetPath);
        }
    }
}
